﻿using System;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using BrnMall.Core;

namespace BrnMall.CacheManager
{
    /// <summary>
    /// BrnMall缓存管理类
    /// </summary>
    public static partial class BMACache
    {
        private static object _locker = new object();//锁对象
        private static ICacheStrategy _icachestrategy = null;//缓存策略
        private static ICacheManager _icachemanager = null;//缓存管理

        static BMACache()
        {
            try
            {
                
                    string[] fileNameList = Directory.GetFiles(System.Web.HttpRuntime.BinDirectory, "BrnMall.CacheStrategy.*.dll", SearchOption.TopDirectoryOnly);
                var fileName = fileNameList[0]??"";
                var cachName = fileName.Substring(fileName.IndexOf("CacheStrategy.",StringComparison.InvariantCultureIgnoreCase) + 14).Replace(".dll", "");
                var typeName= string.Format("BrnMall.CacheStrategy.{0}.CacheStrategy, BrnMall.CacheStrategy.{0}",cachName );
                var type = Type.GetType(typeName, false, true);
                if(type!=null)
                    _icachestrategy = (ICacheStrategy)Activator.CreateInstance(type);
                
            }
            catch
            {
                Trace.TraceWarning("缓存初始化失败");
                _icachestrategy=new NoCacheStrategy();
            }
            _icachemanager = new CacheByRegex();
        }

        public static string Name => _icachestrategy.Name;

        /// <summary>
        /// 缓存过期时间
        /// </summary>
        public static int TimeOut
        {
            get
            {
                return _icachestrategy.TimeOut;
            }
            set
            {
                lock (_locker)
                {
                    _icachestrategy.TimeOut = value;
                }
            }
        }

        /// <summary>
        /// 获得指定键的缓存值
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <returns>缓存值</returns>
        public static T Get<T>(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
                return default(T);
            return _icachestrategy.Get<T>(_icachemanager.GenerateGetKey(key));
        }

        /// <summary>
        /// 将指定键的对象添加到缓存中
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="data">缓存值</param>
        public static void Insert<T>(string key, T data)
        {
            if (string.IsNullOrWhiteSpace(key) || data == null)
                return;
            lock (_locker)
            {
                _icachestrategy.Insert(_icachemanager.GenerateInsertKey(key), data);
            }
        }

        /// <summary>
        /// 将指定键的对象添加到缓存中，并指定过期时间
        /// </summary>
        /// <param name="key">缓存键</param>
        /// <param name="data">缓存值</param>
        /// <param name="cacheTime">缓存过期时间</param>
        public static void Insert<T>(string key, T data, int cacheTime)
        {
            if (string.IsNullOrWhiteSpace(key) || data == null)
                return;
            lock (_locker)
            {
                _icachestrategy.Insert(_icachemanager.GenerateInsertKey(key), data, cacheTime);
            }
        }

        /// <summary>
        /// 从缓存中移除指定键的缓存值
        /// </summary>
        /// <param name="key">缓存键</param>
        public static void Remove(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
                return;
            lock (_locker)
            {
                foreach (string k in _icachemanager.GenerateRemoveKey(key))
                    _icachestrategy.Remove(k);
            }
        }

        /// <summary>
        /// 清空缓存所有对象
        /// </summary>
        public static void Clear()
        {
            lock (_locker)
            {
                _icachestrategy.Clear();
            }
        }
        /// <summary>
        /// 是否存在
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool Exists(string key)
        {
            lock (_locker)
            {
                return _icachestrategy.Exists(key);
            }
        }

        
    }
}
